How would I implement the contains_user function in Domain-Driven-Design?
This is (subtly) the wrong question.
Domain Driven Design is a guideline that cares about how to design your domain. It does not care about how to minimize your memory footprint or IO bandwidth when fetching data from an external storage device. You've not found this information simply because that's not what that guideline is focusing on.
Purism of any approach is often an idealistic goal that tend to become very cost-ineffective the closer you try to get to that 100% purity goal. This is why developers often preach pragmatism over dogma, i.e. the ability to use your common sense to understand when pursuing an ideal becomes counterproductive to what you're actually trying to achieve.
Performance-wise contains_user
would best be implemented directly as DB query inside the function. But that would break DDD.
Following on from the point I was making, a codebase shouldn't really be "DDD and nothing else". So what you call breaking DDD, I call having a pragmatic codebase that doesn't chase DDD purism as its sole goal. Let's compromise and agree to call it breaking away from DDD purism. The subsequent claim I'm going to make is that this is not problematic in and of itself, as long as you're making an informed decision in doing so.
So what do you do then, if not pure DDD?
It is hard to answer the question the right way for you personally, because I don't have a read on where you draw the line on what would be too much effort/load before you agree to deviate from the DDD ideal.
Most commonly, assuming this is a simple key check with no real business logic behind it, I would omit this from the domain, instead having the application layer talk to the persistence layer directly, so it can run a simple contains check without needing to load any data.
My justification for this is that this is an optimization that supplants the domain driven way of doing this, and the benefit (not having to load the entire list in memory) far outweighs the cost (a deviation from the DDD ideal).
If you want to stick more to DDD, or there is more domain logic to performing this check (e.g. you need to also account for the date on which they were/n't part of the group, or their inclusion in the group is contingent on another condition that needs to be checked), then I would consider designing a separate domain object whose specific responsibility is to perform these checks. Call it a validator/checker or whatever makes the most sense contextually.
This also nudges you towards considering this "membership" as an aggregate root of its own, alongside users and groups. Whether or not this should be explicitly defined as a bounded context depends on whether you have sufficient use cases to justify the cost of creating it.
Personally, I tend to have my domain define my persistence interfaces (not implementations of course), and I don't think it's wrong for domain logic to interact with said interface. In that context, this means that the checker/validator (or membership aggregate root) is therefore perfectly capable of interacting with the persistence layer intelligently, so as to avoid loading more data than is strictly necessary for it to do its job.