The only generic semi-automatic procedure I can think of would be to delete post meta where the post_id is invalid.
SELECT *
FROM {$wpdb->postmeta} as pm
LEFT JOIN {$wpdb->posts} as p
ON pm.post_id = p.ID
WHERE p.ID IS NULL
I wrote a SELECT and not a DELETE because I don’t trust that to work in all cases. I have seen “dummy” or “placeholder” values in the postmeta table with a post_id of 0 or some absurdly high value. I am not saying those are good ideas, but I have seen that, so be aware. You are better off looking over the data returned by that SELECT and then deleting items selectively.
I don’t really expect to get very far a post meta makes very little sense without post, except for a few questionably wise uses.
The other, very labor intensive thing you can do is look at the meta_keys in the database and try to spot keys belonging to plugins that you no longer use. It may or may not be possible to identify them, but you can try. Some plugins use identifiable prefixes or suffixes.