You can also use it when writing a block of code where you haven't decided what kind of functional abstractions or data structures you want. Write the code you wish you could write. Then fill in the code needed to support that.
You can use the two to figure out what is the time complexity for a solution that would work. This simplifies the search for a solution by quite a bit. Here's a blog post about this idea (going from the input constraint to the possible algorithm): https://www.infoarena.ro/blog/numbers-everyone-should-know
Other than that, understanding a set of frequent data structures and algorithms helps a ton. Here's a short course from stanford on preparing for coding contests http://web.stanford.edu/class/cs97si/
"How to solve it" [1] was helpful for me in this regard, but it isn't really condensed like this blog post.
After you finish "how to solve it", you can read the more advanced "Mathematics and Plausible Reasoning" [2]
[1] https://www.amazon.com/How-Solve-Mathematical-Princeton-Scie... [2] https://www.amazon.com/Mathematics-Plausible-Reasoning-Two-V...
https://malisper.me/an-algorithm-for-passing-programming-int...
of course, it's important (for better or worse) to just grind out a representative sample until you understand most common patterns, e.g: https://seanprashad.com/leetcode-patterns/