Which environment type is the code to run in? Often it is far better to match existing paradigms of behavior than to strike out on your own way of doing things.
When you ask for a element from an empty abstract list, does it throw an exception? If so, it is far better to make popping off a non-full stack throw an exception.
Undefined behavior is a bad choice when it is trivially easy to define the behavior.
If most of the code returns items via the return statement, then returning a control (bool for if it worked) is a bad design. If most of the code returns items via the parameter list, then returning a control via the return statement is a good design provided that the other calls on similar collections do likewise.
An empty element doesn't make a lot of sense, it becomes a magic value. For example, if I create a list and push five empty elements in it, is it the same as a list with no empty elements in it? Is it the same as a list with one empty element in it? Is it the same a list with some elements and an empty element in it? Empty lists being a "special" object is one thing, but empty elements are problematic because they don't really contain the behavior of the element, they contain the behavior of the list. Good object orientation has contents of the behavior encapsulated in the same object it describes.
Note that empty elements are not the same as sentinels. Sentinels are implementation details contained within a collection (and ideally should never be exposed externally). When I read "returns an empty element", I think one would have to be intimately knowledgeable about the implementation of the stack to use it. Too much intimacy between classes is called tight coupling, and it can make the code much more difficult to modify / fix / change going forward.
If you do strike out on your own way of doing things, then you should minimally make your entire side of the code behave the same. It makes it easier to read an maintain.