The top one for me has been to try working with as many technologies as possible. Do something in every environment you can – write some C, some Ruby, Python, Java, Swift, Typescript, C++, Haskell, Rust, Objective C… whatever you can get your hands on. Every language and framework you use—even if just for a minor project—will expose you to a set of new ideas, idioms, and APIs. After a while you start to recognise all of the different patterns, and understand how and why they work in the way they do. I think this is effective if you're the sort of person who learns more effectively from practice than from research.
The other one is to always be thinking about that well-known Torvalds quote:
"Bad programmers worry about the code. Good programmers worry about data structures and their relationships."
We often think of "programming" as "writing code" - but that's really just a tool to an end, and the best code is the code you didn't have to write. Approaching problems by thinking about the shape of the data you have, what you want it to look like, and the relationship between these things sometimes feels like a superpower. The code is just the annoying bit in the middle that helps you do all that stuff.
The other one is to always be thinking about that well-known Torvalds quote:
"Bad programmers worry about the code. Good programmers worry about data structures and their relationships."
We often think of "programming" as "writing code" - but that's really just a tool to an end, and the best code is the code you didn't have to write. Approaching problems by thinking about the shape of the data you have, what you want it to look like, and the relationship between these things sometimes feels like a superpower. The code is just the annoying bit in the middle that helps you do all that stuff.