What is the alternative of the combination of two pattern matching conditions?
If first and second can be any value and could be embedded in other words without any kind of delimiter (eg, foofirstbar), then yes, using trigrams is probably as good as you're going to get. If there are a limited number of values for first and second, you could create an expression index of the name column passed through a regexp_replace to add spaces around your target words, and then use the built-in full-text-search functionality:

testdb=# create table data(t text);
CREATE TABLE
testdb=# insert into data select 'foofirstbarsecondbaz';
INSERT 0 1
testdb=# insert into data select 'foobarsecondbaz';
INSERT 0 1
testdb=# insert into data select 'foosecondbarfirstbaz';
INSERT 0 1
testdb=# select t from data where 'first &amp; second'::tsquery @@ regexp_replace(t, '(first|second)', ' \1 ', 'g')::tsvector;
          t           
----------------------
 foofirstbarsecondbaz
 foosecondbarfirstbaz
(2 rows)