Stack without duplicates
Here is the solution I found. I suppose here that the values entering the stack will be in $[\![0, n-1]\!]$. For that, I create an array $a$ of size $n$ that will implement a kind of doubly linked list: it is such that for $i \in [\![0, n-1]\!]$, $a[i] = (p_i, n_i)$ where:

if $i$ is not in the stack, $(p_i, n_i) = (-2, -2)$;
if $i$ is in the stack, $p_i$ (previous) is the value that is above $i$ in the stack ($-1$ if $i$ is the top of the stack) and $n_i$ (next) is the value that is below $i$ in the stack ($-1$ if $i$ is the bottom of the stack).

The stack is then a couple $(i_0, a)$, where $i_0$ is the top element of the stack ($-1$ if the stack is empty).
That way, the usual operations on stack can be done in $O(1)$ worst case:

testing emptyness: just check if $i_0 = 1$ or not;
pushing element $i$:

if $a[i] = (-2, -2)$, $a[i] \leftarrow (-1, i_0)$ then $i_0 \leftarrow i$
if $a[i] = (p_i, n_i)$ (duplicate case), then $a[p_i] \leftarrow (p_{p_i}, n_i)$, $a[n_i] \leftarrow (p_i, n_{n_i})$ (only if $p_i/n_i\neq -1$), $a[i] \leftarrow (-1, i_0)$ then $i_0 \leftarrow i$


popping element: $i\leftarrow i_0$, $i_0 \leftarrow n_{i_0}$ $a[i] \leftarrow (-2, -2)$, return $i$.

In the case of the DFS, one can also add the case $a[i] = (-3, -3)$ to differentiate vertices that already exited the stack from the $a[j] = (-2, -2)$, vertices that have not already entered the stack. The array a can then replace the boolean array usually used.