tl;dr install this user script, and it becomes possible to vote to close for old close reasons such as "not constructive" and "too localized".
After doing some twiddling with Stack Exchange JavaScript, I discovered it's possible to vote to close for old, now-decommissioned close reasons such as "not constructive", "not a real question", and "too localized".
While writing my own script to cast close votes, I discovered that it's possible to cast votes for reasons that can no longer be selected. Basically, the server only checks to see if the close reason ID is valid, without checking to see if the reason is one of the ones that can actually be selected.
Awesome Poodles has written a user script that adds these close reason options back into the close voting UI, as a proof of concept. (Note that the old "exact duplicate" reason is missing from that script because I couldn't figure out how to pass dupe targets to it.)
If you're a 3k+ user, you'll notice an existing close vote, but no close reason is specified. This is because the close vote is for "not constructive"; to see this in action, install the user script and vote to close this as "not constructive", and if it reaches five such close votes, it will be closed as not constructive.
I tested this out, and this script does work for <3k users (it will cast a recommend closure flag), and it also works within Stack Overflow for Teams, where all users have binding close vote privileges.
Can this please be fixed? As far as I could tell, the only good reason for keeping this workaround was because it previously wasn't possible to close Teams questions as off-topic (only as duplicate), and this workaround would allow for it, but now that an official off-topic reason has been implemented for Teams, I see no reason to keep it around, as it allows users to vote for close reasons that were removed for good reason.