> First, he basically tells me this project should have been finished a long time ago and he can't believe it's taken this long etc. I had no idea that he felt this way before the meeting - I've mostly just been working to get it done before the revised deadline my manager gave me.
You need to communicate, build relationships, and get feedback from many people in the organization. One of those people is your manager's manager.
> He looks at the code and criticizes design decisions, some of which were made largely on my manager's explicit suggestions.
It may be the case that your manager is wrong, his design suggestions were dumb, etc. Or, it may not. This is one reason you need to get feedback from people other than your manager.
> Part of the reason it had taken so long is because I put a substantial amount of work into a part of the project that's no longer necessary due to changing requirements, which I don't think I could have forseen.
Use this as a learning experience. Do not put work into things that may or may not be needed. The correct way to tackle a big project with changing requirements is to get something working end-to-end, possibly with a whole lot of copy and paste, hacks, hardcoded stuff instead of configuration, whatever. Then, when it is doing what it supposed to do, go back and improve it, rinse and repeat. Do not put lots of work into one part if other parts are missing, non-existent, and the project doesn't work end-to-end.
> For instance he said I should have looked at other projects to see how they accomplished what I'm trying to do.
This is great advice. It is often the case that if you ask the right question/person, someone will say "oh, yeah, I already did that, here's the code." or "I tried that last year, and it didn't work". Or, they might not, but the only way is to ask around, talk to people. This also goes back to the first point, build relationships with people other than your manager, because your manager doesn't know everything, and is probably wrong about a bunch of stuff.