You learn from experience. Trial and error, experiment, and mentoring. You study code that works and code that doesn’t.
This isn’t practical for large code bases, but you can do it with individual functions and chunks of code. I still work this way but I don’t think it’s a common technique anymore.