Cycle in Directed graph to vector
General stuff


#includes are missing
missing using namespace std; (which by itself is discouraged, especially in header files).
Graph::cycles path result contains not only the cycle, but alse the vertices that led there (e.g. in A -&gt; B -&gt; C -&gt; B, A would be included in path though it is not part of the cycle). This might or might not be intended.
Inconsistency: Graph::cycleHelper takes visited as bool[], but recStack as bool *, even though the usage for both is the same.
if(visited[v] == false) can easily be rewritten to if(!visited[v])
Graph::cycle treats path as if it has full control over all elements already present. This behavior might be unexpected by users of the class and should at the very least be thouroughly documented.


Memory management


Graph::cycle leaks both visited and recStack.
Graph::addEdge never checks whether its parameters are in the valid range. If they aren't, there might be accesses to out-of-bounds memory.


These issues can be fixed by using appropriate data structures and error checking. Generally, prefer using RAII constructs (like std::unique_ptr or containers) for resource acquisition.

Data structures


Prefer std::array (if size is statically known) or std::vector (if not) over raw arrays. This also helps with memory cleanup.
Try to structure similarly used variables in their own class or struct.
Prefer std::vector (preferred) or std::deque (if constant time frontal insertion/removal is needed) over std::list, unless you absolutely need constant time random insertion/removal (and even then, you might want to measure std::vector as it is surprisingly efficient on modern hardware).


Class design


Some variables have very cryptic names and few (if any) documentation to their meaning.


Graph::V: Represents the number of vertices in the graph. Maybe rename to vertex_count or num_vertices or similar.
u and w in Graph::addEdge: There is not way to infer whether the edge is added from u to w or vice versa. Maybe rename to something like from and to?
Graph::cycle: cycle is an unfornate choice of name, as the verb cycle has a different meaning. hasCycle or findCycle better express the intention behind this member function.

There is an implicit assumption that "vertex index" == "vertex value". If there ever is a case where this assumption does not hold, the whole class will have to be redesigned.
Graph::cycle violates the Single Responsibility Principle (SRP). It does two things ("check whether there is a cycle" and "return the cycle"), which might benefit users of the class that want both operations, but hinders other users that only want one of the operations.
Graph is built upon the assumption that no more vertices will be added after construction. While this might be true in your specific use case, this won't be true in general.
A specific edge might be added multiple times, which might increase worst case runtimes (as iteration of the edges of a vertex can become greater than \$\mathcal{O}(n)\$


Amending all the points

If I had to implement this, the result would look like this:

#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;stdexcept&gt;
#include &lt;deque&gt;

class graph {
    using node_type = int;

    class vertex {
        node_type value;
        std::vector&lt;vertex *&gt; edges;
        bool visited = false;
        bool marked = false;

    public:
        vertex(node_type name) : value{name}, edges{} {}

        node_type name() const { return value; }
        bool is_marked() const { return marked; }
        void clear_flags() { visited = false; marked = false; }

        bool has_edge(vertex *to) const {
            return std::find(std::begin(edges), std::end(edges), to) != std::end(edges);
        }
        void add_edge(vertex *to) {
            if(!has_edge(to)) edges.push_back(to);
        }

        vertex *find_first_marked_edge() {
            auto match = std::find_if(std::begin(edges), std::end(edges), [](auto&amp; edge){ return edge-&gt;marked; });
            if(match == std::end(edges)) return nullptr;

            return *match;
        }

        bool is_part_of_cycle() {
            if(marked) return true;
            if(visited) return false;

            visited = true;
            marked = true;

            for(auto&amp; edge : edges) {
                if(edge-&gt;is_part_of_cycle()) return true;
            }

            marked = false;
            return false;
        }
    };

    std::vector&lt;vertex&gt; vertices;

public:
    graph() = default;
    graph(std::initializer_list&lt;node_type&gt; init) : vertices{} {
        for(auto&amp; name : init) {
            add_vertex(name);
        }
    }

    void add_vertex(const node_type&amp; name) {
        if(std::find_if(std::begin(vertices), std::end(vertices), [&amp;](auto&amp; vert){ return vert.name() == name; }) != std::end(vertices)) {
            throw std::invalid_argument{"a vertex with this name already exists"};
        }
        vertices.emplace_back(name);
    }

    void add_edge(node_type from, node_type to) {
        auto&amp; from_vert = find_vertex(from);
        auto&amp; to_vert = find_vertex(to);

        from_vert.add_edge(&amp;to_vert);
    }

    bool has_cycle() {
        for(auto&amp; vert : vertices) {
            vert.clear_flags();
        }

        for(auto&amp; vert : vertices) {
            if(vert.is_part_of_cycle()) return true;
        }

        return false;
    }

    std::deque&lt;node_type&gt; find_first_cycle() {
        auto cycle = std::deque&lt;node_type&gt;{};
        if(!has_cycle()) return cycle;

        auto cycle_iter = find_first_marked_vertex();

        while(std::find(std::begin(cycle), std::end(cycle), cycle_iter-&gt;name()) == std::end(cycle)) {
            cycle.push_back(cycle_iter-&gt;name());
            cycle_iter = cycle_iter-&gt;find_first_marked_edge();
        }

        while(cycle.front() != cycle_iter-&gt;name()) cycle.pop_front();

        return cycle;
    }

private:
    vertex&amp; find_vertex(node_type name) {
        auto match = std::find_if(std::begin(vertices), std::end(vertices), [&amp;](auto&amp; vert){ return vert.name() == name; });
        if(match == std::end(vertices)) {
            throw std::invalid_argument{"vertex could not be found"};
        }

        return *match;
    }

    vertex* find_first_marked_vertex() {
        auto match = std::find_if(std::begin(vertices), std::end(vertices), [](auto&amp; vert){ return vert.is_marked(); });
        if(match == std::end(vertices)) return nullptr;
        return &amp;*match;
    }
};


Points to note:


graph::vertex encapsulates all information about a vertex. I changed recStack to marked, since many graph algorithms work with marked vertices.
No manual memory management (= no memory leaks). Everything is owned by containers.
I introduced some descriptive helper functions. This makes the code much more readable.
If the value of the vertices ever needs to be changed (or templated), only the definition of graph::node_type needs to be adjusted.
For a more deterministic performance, graph::vertex::edges could be kept sorted at all times.
Some functions have a first in their names, as there might be more results (in the general case).