For instance, putting related code into a data structure allows you to add more to it later without replumbing the whole system (as opposed to functions with five arguments).
With enough experience with refactoring, just choosing a structure that’s easy to refactor can serve as an extension point. (I have even tricked people into implementing a feature the way I had it in my head by writing the intermediate version in such a way to suggest a simple change for part 2.)
Try to make sure that reasonable extensions are cheap to add, and that even some of the more unreasonable ones are at least possible without complete system redesign.
This should not significantly impact either implementation time, or design time. But it will almost certainly make you avoid some really bad design choices that make quite plausible changes extremely expensive.
Good design is more about avoiding obvious traps than finding a path to nirvana.
I do a lot of data mining, and the first step is always securing the data source and archiving it. There have been times where I wasn't able to revisit the project and finish the actual parser of the data for 5-6 months, at which point I can run through the old data. Other times, I'll write the parser but we'll only be parsing a subset of the data we acqiured. The additional unparsed portionisn't necessarily without merit, it's just not something we are dealing with yet (either because it's still of an unknown quality, or requires more effort than we want to spend at that moment). Knowing it's there and that it may need to be parsed in the future can subtly affect your design such that you leave yourself the openings you'll later need to easily parse this additional data. Sometimes that's as simple as just avoiding situations that would make it extremely cumbersome later, and not necessarily actively making it easier.
I'm not sure ignoring something as obvious as this makes one a good developer, but what's "obvious" and what isn't is actually quite different at different software engineering experience levels.
Ignoring cost of change can be absolutely devastating in the long run, but believing you can somehow scry the future for all possible extension points necessary is equally so.
Designing for (anticipated) change in my mind is not at all about adding hooks, API's, or any code at all for that matter.
I think of it more like making sure your system respect analogues to gravity and the other natural laws as best translated into the more abstract relations relevant for the particular kind of system you are building.
One could call it programmer and refactoring friendly design and not miss the target by much.
I've gradually become convinced of just the opposite: a good developer doesn't think ahead at all. The best way to prepare for the evolution of business needs isn't to add extension hooks in the middle of your code, it's to keep the code as simple as possible so that you can change it in a very direct way as and when you need to.