It might be helpful to go through the constructor calls in reverse order.
B b({ A() });
To construct a B, the compiler must call B's constructor that takes a const vector<A>&. That constructor in turn must make a copy of the vector, including all of its elements. That's the second copy ctor call you see.
To construct the temporary vector to be passed to B's constructor, the compiler must invoke the initializer_list constructor of std::vector. That constructor, in turn, must make a copy of what's contained in the initializer_list*. That's the first copy constructor call you see.
The standard specifies how initializer_list objects are constructed in §8.5.4 [dcl.init.list]/p5:
An object of type std::initializer_list<E> is constructed from an
initializer list as if the implementation allocated an array of N
elements of type const E**, where N is the number of elements in the
initializer list. Each element of that array is copy-initialized with
the corresponding element of the initializer list, and the
std::initializer_list<E> object is constructed to refer to that array.
Copy-initialization of an object from something of the same type uses overload resolution to select the constructor to use (§8.5 [dcl.init]/p17), so with an rvalue of the same type it will invoke the move constructor if one is available. Thus, to construct the initializer_list<A> from the braced initializer list, the compiler will first construct an array of one const A by moving from the temporary A constructed by A(), causing a move constructor call, and then construct the initializer_list object to refer to that array.
I can't figure out where the other move in g++ comes from, though. initializer_lists are usually nothing more than a pair of pointers, and the standard mandates that copying one doesn't copy the underlying elements. g++ seems to call the move constructor twice when creating an initializer_list from a temporary. It even calls the move constructor when constructing an initializer_list from a lvalue.
My best guess is that it's implementing the standard's non-normative example literally. The standard provides the following example:
struct X {
X(std::initializer_list<double> v);
};
X x{ 1,2,3 };
The initialization will be implemented in a way roughly equivalent to
this:**
const double __a[3] = {double{1}, double{2}, double{3}};
X x(std::initializer_list<double>(__a, __a+3));
assuming that the implementation can construct an initializer_list object with a pair of pointers.
So if you take this example literally, the array underlying the initializer_list in our case will be constructed as if by:
const A __a[1] = { A{A()} };
which does incur two move constructor calls because it constructs a temporary A, copy-initializes a second temporary A from the first one, then copy-initializes the array member from the second temporary. The normative text of the standard, however, makes clear that there should only be one copy-initialization, not two, so this seems like a bug.
Finally, the first A::A comes directly from A().
There's not much to discuss about the destructor calls. All temporaries (regardless of number) created during the construction of b will be destructed at the end of the statement in reverse order of construction, and the one A stored in b will be destructed when b goes out of scope.
* The initializer_list constructors of standard library containers are defined as being equivalent to invoking the constructor taking two iterators with list.begin() and list.end(). Those member functions return a const T*, so it can't be moved from. In C++14, the backing array is made const, so it's even clearer that you can't possibly move from it or otherwise change it.
** This answer originally quoted N3337 (the C++11 standard plus some minor editorial changes), which has the array having elements of type E rather than const E and the array in the example being of type double. In C++14, the underlying array was made const as a result of CWG 1418.