The concept of reducing the cost of change is a one of the core values of agile practitioners. In essence, it boils down to being able to make changes when we want them. Practices such as TDD and Iterations enable us to actually make changes without attaching a high price point for them. Some tools make change much easier than others. Using NHibernate, I can evolve my data model (and notice that I am explicitly talking about data models, not domain models. This is using NHibernate just for DTO mapping) much more rapidly than if I am using SP or code gen. If I have a real domain model, then that is even easier, in most cases.
But it is neither the tools not the practices that actually enable change. They are not even significantly responsible for reducing the cost of change. Beyond anything else, it is the will of the team to accept the pain of making the change and actually doing this.
I recently had a meeting in which I presented a demo of my current project. During the meeting, we hashed together what the application is doing, and in what way it is supposed to work. By that afternoon, I was able to get it to work using the new model. It involved breaking the entire application to pieces and restructuring it from the fragments. That wasn't pleasant, and it took me half a day of just trying, but it was done.
When I demoed it to the client in the same afternoon, he was quite pleased. I am not sure that I managed to covey the actual reason that I was able to affect such a change in the application. It doesn't have anything to do with technology, it has to do with a mindset. I would have been able to do the same if the application was written using ASP Classic with Stored Procedures, not as easily, maybe, but within roughly the same time frame.
That mindset, at least for me, starts from the first line of code. I treat each piece of the project as utterly disposable. Since I don't really care how each individual piece works, I am able to roughly sketch a fair amount of the application very rapidly, and then focus on each of the items in isolation, and replace that with a much better implementation. I think that I stated before that I tend to rewrite most of my application core at least two or three times before I am happy with them.
When you have disposable pieces, it is no big deal if you mess up and need to start over, because the whole project is structured in a way that allows you to do so. Going back to using my current project as an example, the algorithm used for the core part of the system is crap. I thought it up while being on a coffee break, and it is enough to demonstrate what the software is supposed to be doing. I don't really care, because the moment that I do need the real algorithm, I can drop it in (need to change the implementation of a single method).
But it is not just preparing ahead. It is also just plain willingness to do the work. About a year or two ago we (Castle Team) wanted to be make document all the public API for Castle Active Record. If I recall correctly, I did it by asking the compiler to break the build if we didn't have an appropriate XML comment for all out public types and members. There were some 800 build errors. And the only way to fix them was to go and document all of them. It took several days, but then it was done.
I don't think it was pleasant by any stretch of the word, but by trying we were able to make it happen.
So, to conclude, the best way I know to reduce the cost of change is to actually accept change. After that, the reduction will happen on its own.