Finding hash match aggregate
It is not possible to directly connect part of the query text (e.g. GROUP BY) with a specific operation in the final execution plan.

You can write a query to find plans that:


Contain a Hash Match Aggregate; and
The query text contains a GROUP BY clause


...which is not quite the same thing, since this will find plans where the grouping logic was implemented using a Stream Aggregate, replaced with another operation, or even removed entirely - but happens to also contain a Hash Match Aggregate for some other reason.

For example:

WITH XMLNAMESPACES
(
    DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan'
)
SELECT
    DECP.cacheobjtype,
    DECP.objtype,
    DECP.plan_handle,
    DEQP.objectid,
    DEQP.query_plan,
    DEST.[text]
FROM sys.dm_exec_cached_plans AS DECP
CROSS APPLY sys.dm_exec_query_plan(DECP.plan_handle) AS DEQP
CROSS APPLY sys.dm_exec_sql_text(DECP.plan_handle) AS DEST
WHERE
    1 = DEQP.query_plan.exist(
        '//RelOp[
            @PhysicalOp = "Hash Match"
            and @LogicalOp = ("Aggregate","Partial Aggregate","Flow Distinct")]')
    AND DEST.[text] LIKE N'%GROUP BY%';


This might miss some GROUP BY queries if they have a different amount (or type) of white space between GROUP and BY than expected by the query. Maybe replacing all white space with spaces and collapsing contiguous ones into a single space could be done before the LIKE or use SQLCLR and regex instead.

You would need to inspect the results by hand to determine if the Hash Match Aggregate correlates directly to the GROUP BY clause or not. The query above could be extended, perhaps, to check the plan HashKeysBuild element against the grouping columns, but this would be hard to get right, due to optimizer operations.