A relevant technique worth mentioning is using a second compiler. Clang has invested in better error messages, for instance, but any alternative way to phrase the error can be enlightening. 

This is especially so for the most complex type of errors. For instance, when you mix up two similar constructs (not unusual for beginners), compilers typically have a problem in generating the right error message. This can cause confusion when the compiler gives an error message about the incorrect usage of construct A when you actually intended construct B. A second compiler might infer that you intended B.