Taxonomy terms can still be added when only assign_terms capability has been granted

As far as capabilities are concerned there is no distinction between creating new terms and assigning them to posts. So it’s not possible through capabilities alone to only allow users to assign pre-defined terms. This likely has its roots in the UI which, especially for tags, is designed around creating terms when writing posts. The UI does not have a selection-only state.

The usual method of customising the behaviour of capabilities, which is using the map_meta_cap filter, will not work either. This is because there is no reliable way to know whether a check against assign_terms is a check for assigning a term, or creating one.

Your only option may be to implement your own custom UI, with your back end layer that can handle requests to create terms after checking your own custom capability.