Great question!
The trivial but not exactly helpful answer is “you have to know or find out.”
As Nikolay pointed out, any variable that is shared by different threads of execution is a potential candidate. The poster case here is a circular buffer that is filled by one thread of execution and emptied by another thread. If the buffer is implemented as a linked ist, the list may get corrupted if it is temporarily broken by one thread (in order to splice in another element) but concurrently read by another thread before restored. Likewise if it is implemented as an array where the front and back pointers may be subjected to interleaved R-M-W cycles as Nikolay sketched (btw, some CPUs have native support for hardware atomicity of, say, increment and decrement, but you can not necessarily rely on the compiler generating the right code for it).
Yet there are use cases in which there is no danger of incoherency even in those cases.
In practice, what happens is that you scratch your head over some intermittent fault that you can’t explain for the life of you, until after weeks of debugging you find that you encountered a case of unserialized access to a shared variable/peripheral.
A good practice to help preventing such bug hunts is to encapsulate all accesses to variables in structures or C++ classes and make it a habit to make a comment in each function header that reads “this method called in the context of <thread abc|isr xyz>.”
Some development groups also make it a habit to preventively wrap every access to a member variable of certain classes into a mutex lock just to be on the safe side. I consider that a bad habit as too much synchronization is as bad as not enough of it, so by overserializing code where unneeded has potential for follow up problems (for example starvation following on priority inheritance or deadlock potential).
So a lot of it is experience and having learned to think “horizontally” (multithreaded) instead of “vertically” (in terms of pure serial control flow).
Sorry I can not be more helpful, but this is an area that to my best knowledge is not yet formalized or studied in depth. Richard has provided a few useful pointers.