Tests should be isolated. That is the way Cucumber is designed, and there's a very good reason for it. I would strongly urge against it unless you absolutely have to.
If you have something that needs to be executed before your entire test suite, consider a @BeforeAll hook.
That said, I've come across this before. We had tests which would start a process that took a long time (such as provisioning a VM, which would take 10 minutes a time..), but could be skipped in other tests if it had already been done.
So you may want to design steps along the lines of..
"Given that .. X has been done"
and in the step detect whether X is done or not, and if not, then do X. If it has, then skip it. For example, say creating users is a process that takes absolutely ages. Then we could do..
Given that user "Joe Bloggs" has been created
The step definition would first try to determine if Joe existed, and then if they didn't, create the user. You have an initial start up problem, but then other tests will be able to safely assume Joe exists.
WHY YOU SHOULD NOT DO THIS
If you do this, there's a high probability your tests will conflict with one another.
Say you have lots of tests that use the Joe Bloggs user. Maybe some will delete him from the system. Some might temporarily deactivate the user, add roles, change their name.. all sorts of things. All tests assume certain things about the system they're testing, and you are intentionally harming your tests assumptions about the environment.
It's particularly bad if you are running parallel tests. Maybe your system has a restriction that only one person can log in at a time as Joe. Or every test is changing loads of things about Joe, and no test can assume anything about the state of the Joe user. Then you'll be in a huge mess.
The best solution is often to create brand new data for each test you run. Open up those APIs and create disposable data for each test run. Here's a good blog post about it: https://opencredo.com/test-automation-concepts-data-aliases/