After you deploy a custom MigrationStep (say, after renaming a property), should the MigrationStep class remain in the code base or is it safe to delete?
It is safe to delete.
Personally I tend to just comment it out, to have it easy accessible the next time I need to do the same thing.
Sure. After a migration step has run on all your environments, it is safe to delete it from code.
Comment from source code of EPiServer.DataAbstraction.Migration.MigrationStep:
/// There is no versioning handling in a migration step. It is intended to be a very specific class for specific databases.
/// It is safe to remove the migration step implementation after the changes described in it have been commited to the database.